﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace AgLux
{
    /// <summary>
    /// Represents a component that displays a video clip.
    /// </summary>

    public class Video : Media
    {
        /// <summary>
        /// Initializes a new instance of the Video class.
        /// </summary>

        /// <param name="source">
        /// The source of the video.
        /// </param>

        /// <param name="caption">
        /// The caption of the video.
        /// </param>

        /// <param name="transcript">
        /// The video transcript source.
        /// </param>

        /// <param name="filling">
        /// The video width as a percentage of the parent canvas width.
        /// </param>

        public Video(string source, string caption, string transcript, Filling filling)
            : base(source, caption, transcript, (double)filling / 100)
        {
            _enterMediaFullScreen.MouseLeftButtonDown += new MouseEventHandler(EnterFullScreen);
            _leaveMediaFullScreen.MouseLeftButtonDown += new MouseEventHandler(LeaveFullScreen);

            _screen.MouseMove += new MouseEventHandler(ShowPanel);
            _panelArea.MouseEnter += new MouseEventHandler(FocusPanel);
            _panelArea.MouseLeave += new EventHandler(UnfocusPanel);

            _second.Completed += new EventHandler(CheckPanel);
            _mediaPanelScaleUp.Completed += new EventHandler(TimePanel);
            _mediaPanelScaleDown.Completed += new EventHandler(HidePanel);
        }

        /// <summary>
        /// Prepare to display the media.
        /// </summary>

        /// <param name="width">
        /// The width of the canvas on which the media will be displayed.
        /// </param>

        public override void Prepare(double width)
        {
            base.Prepare(width);
            _screen.Width = _media.Width = width * _filling;
            _panelArea.Width = width / 2;

            if (_filling < 0.5)
            {
                _panelArea.Width = _screen.Width;
            }
            _mediaPanelScaleUpX.Value = _mediaPanelScaleUpY.Value = _mediaPanelScaleDownX.Value = _mediaPanelScaleDownY.Value = _panelArea.Width / _mediaPanel.Width;

            _panelArea.Height = _mediaPanel.Height * (double)_mediaPanelScaleUpX.Value;
            _panelArea.SetValue(Canvas.LeftProperty, _screen.Width / 2 - _panelArea.Width / 2);
            _mediaPanel.SetValue(Canvas.LeftProperty, _panelArea.Width / 2 - _mediaPanel.Width / 2);
            _mediaPanel.SetValue(Canvas.TopProperty, _panelArea.Height - _mediaPanel.Height);

        }

        /// <summary>
        /// Ends the activity of the media.
        /// </summary>

        public override void End()
        {
            base.End();
            _second.Stop();
            _mediaPanelScaleUp.Stop();
            _mediaPanelScaleDown.Stop();

            _mediaPanelScale.ScaleX = _mediaPanelScale.ScaleY = 0;
            _isShowingPanel = _isFocusingPanel = false;
        }

        /// <summary>
        /// Occurs when it is time to start the activity of the media.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected override void Start(object sender, EventArgs args)
        {
            base.Start(sender, args);
            _screen.Height = _media.Height;
            SetCaption(_screen.Width);
            Height = _media.Height + _caption.Height + 5;

            _panelArea.SetValue(Canvas.TopProperty, _screen.Height - _panelArea.Height);
            _caption.SetValue(Canvas.TopProperty, Height - _caption.Height);

        }

        /// <summary>
        /// Occurs when it is time to enter full screen.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The MouseEventArgs that contains the event data.
        /// </param>

        protected override void EnterFullScreen(object sender, MouseEventArgs args)
        {
            base.EnterFullScreen(sender, args);
            double proportion = _media.Width / _media.Height;
            _screen.Width = _media.Width = BrowserHost.ActualWidth;
            _screen.Height = BrowserHost.ActualHeight;

            if (_screen.Height < _screen.Width / proportion)
            {
                _media.Width = _screen.Height * proportion;
                _media.SetValue(Canvas.LeftProperty, (_screen.Width - _media.Width) / 2);
            }
            else
            {
                _media.SetValue(Canvas.TopProperty, (_screen.Height - _screen.Width / proportion) / 2);
            }

            _panelArea.Width = _mediaPanel.Width;
            _panelArea.Height = _mediaPanel.Height;
            _panelArea.SetValue(Canvas.LeftProperty, _screen.Width / 2 - _panelArea.Width / 2);
            _panelArea.SetValue(Canvas.TopProperty, _screen.Height - _panelArea.Height);

            _mediaPanel.SetValue(Canvas.LeftProperty, 0);
            _mediaPanel.SetValue(Canvas.TopProperty, 0);
            _mediaPanelScaleUpX.Value = _mediaPanelScaleUpY.Value = _mediaPanelScaleDownX.Value = _mediaPanelScaleDownY.Value = 1;
            _caption.Visibility = Visibility.Collapsed;

            _enterMediaFullScreen.Visibility = Visibility.Collapsed;
            _leaveMediaFullScreen.Visibility = Visibility.Visible;
            _showTranscript.MouseLeftButtonDown -= _showTranscriptPressHandler;
            _showTranscriptColor1.Color = _showTranscriptColor2.Color = _showTranscriptColor3.Color = Colors.Black;
            
            _second.Stop();
            _mediaPanelScaleUp.Stop();
            _mediaPanelScaleDown.Stop();

            _mediaPanelScale.ScaleX = _mediaPanelScale.ScaleY = 1;
            _isShowingPanel = true;
            _isFocusingPanel = false;
        }

        /// <summary>
        /// Occurs when it is time to levave full screen.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The MouseEventArgs that contains the event data.
        /// </param>

        protected override void LeaveFullScreen(object sender, MouseEventArgs args)
        {
            base.LeaveFullScreen(sender, args);
            double proportion = _media.Height / _media.Width;
            Prepare(Width);
            _screen.Height = _media.Width * proportion;

            _media.SetValue(Canvas.LeftProperty, 0);
            _media.SetValue(Canvas.TopProperty, 0);
            _panelArea.SetValue(Canvas.TopProperty, _screen.Height - _panelArea.Height);

            _leaveMediaFullScreen.Visibility = Visibility.Collapsed;
            _enterMediaFullScreen.Visibility = Visibility.Visible;
            _caption.Visibility = Visibility.Visible;

            if (_transcript != null)
            {
                _showTranscript.MouseLeftButtonDown += _showTranscriptPressHandler;
                _showTranscriptColor1.Color = _showTranscriptColor3.Color = Color.FromRgb(150, 150, 150);
                _showTranscriptColor2.Color = Colors.White;
            }

            _second.Stop();
            _mediaPanelScaleUp.Stop();
            _mediaPanelScaleDown.Stop();

            _mediaPanelScale.ScaleX = _mediaPanelScale.ScaleY = 0;
            _isShowingPanel = _isFocusingPanel = false;
        }

        /// <summary>
        /// Occurs when it is time to show the control panel.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The MouseEventArgs that contains the event data.
        /// </param>

        protected virtual void ShowPanel(object sender, MouseEventArgs args)
        {
            if (_isShowingPanel)
            {
                _second.Begin();
            }
            else if (Height > 0)
            {
                _isShowingPanel = true;
                _mediaPanelScaleUp.Begin();
            }
        }

        /// <summary>
        /// Occurs when it is time to focus the control panel.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The MouseEventArgs that contains the event data.
        /// </param>

        protected virtual void FocusPanel(object sender, MouseEventArgs args)
        {
            _isFocusingPanel = true;
        }

        /// <summary>
        /// Occurs when it is time to unfocus the control panel.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected virtual void UnfocusPanel(object sender, EventArgs args)
        {
            _isFocusingPanel = false;
        }

        /// <summary>
        /// Occurs when it is time to check if the control panel should be hidden.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected virtual void CheckPanel(object sender, EventArgs args)
        {
            if (_isShowingPanel && !_isFocusingPanel)
            {
                _mediaPanelScaleDown.Begin();
            }
        }

        /// <summary>
        /// Occurs to time the visibility of the control panel.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected virtual void TimePanel(object sender, EventArgs args)
        {
            _second.Begin();
        }

        /// <summary>
        /// Occurs when it is time to hide the control panel.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected virtual void HidePanel(object sender, EventArgs args)
        {
            _isShowingPanel = false;
        }
    }
}
